
#include <winsock2.h>
#include "sma_frame.h"
#include "crc32.h"
#include "LabviewSocket.h"

extern int callback_Labview_Callback(p_Labview_socket_Data sData);

Labview_socket_Data Lsocket;

int Labview_socket_Init(void)
{
	int ret;

	Lsocket.handle_mutex = CreateMutex(NULL, FALSE, NULL);
	if(Lsocket.handle_mutex == NULL)
	{
		return -1;
	}

	ret = WSAStartup(MAKEWORD(2, 2), &Lsocket.wsa_data);
	if(ret != 0)
	{
		CloseHandle(Lsocket.handle_mutex);
		return -1;
	}

	return 0;
}

int Labview_socket_De_init(void)
{
	int ret;
	int error;

	error = 0;

	ret = WSACleanup();
	if(ret != 0)
	{
		error = 1;
	}

	CloseHandle(Lsocket.handle_mutex);

	return error ? -1 : 0;
}

int Labview_socket_Start(void)
{
	Lsocket.handle_thread = CreateThread(
		NULL,
		0,
		labview_socket_thread,
		NULL,
		0,
		NULL);
	if(Lsocket.handle_thread == NULL)
	{
		return -1;
	}
	printf("Create labview Socket.\n");
	return 0;
}

int Labview_socket_Stop(void)
{
	WaitForSingleObject(Lsocket.handle_thread, INFINITE);
	CloseHandle(Lsocket.handle_thread);
	return 0;
}

//---------------------------------------------------------------------- */

static DWORD WINAPI labview_socket_thread(LPVOID param)
{
	int ret;
	struct sockaddr_in sock_address;
	SOCKET client_socket;

	printf("labview_socket_thread. \n");

	NewSocket:
	Lsocket.listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(Lsocket.listen_socket == INVALID_SOCKET)
	{
		return -1;
	}

	memset(&sock_address, 0, sizeof(sock_address));
	sock_address.sin_family = AF_INET;
	sock_address.sin_addr.s_addr = INADDR_ANY;
	sock_address.sin_port = htons(SERVER_PORT);

	ret = bind(Lsocket.listen_socket, (struct sockaddr *)&sock_address, sizeof(sock_address));
	if(ret != 0)
	{
		closesocket(Lsocket.listen_socket);
		return -1;
	}
	printf("listen started.\n");
	ret = listen(Lsocket.listen_socket, 5);
	if(ret != 0)
	{
		closesocket(Lsocket.listen_socket);
		return -1;
	}
	printf("socket createded. \n");

	while(1)
	{
		printf("waiting client_socket. \n");
		client_socket = accept(Lsocket.listen_socket, NULL, NULL);
		if(client_socket != INVALID_SOCKET)
		{
			printf("client_socket %d \n.",client_socket);
			ret = Labview_Socket_ClientHandler(client_socket);  // loop continue rev/reply 
			if(ret == -1)
			{
				break;
			}
		}
	}

	closesocket(Lsocket.listen_socket);
	goto NewSocket;

	return 0;
}

static int Labview_Socket_ClientHandler(SOCKET client_socket)
{
	int ret;
	int error;
	error = 0;

	printf("start waiting data.\n");

	while(1)
	{
		ret = recv(client_socket, Lsocket.receive_buff, MAX_COMMAND_FRAME_SIZE, 0);
		printf("R");
		if(ret == SOCKET_ERROR)
		{
			error = 1;
			printf("labview_stock error! SOCKET_ERROR when receiving\n");
			break;
		}
		else if(ret == 0)
		{
			//Connection closed. 
			printf("labview_stock error! Connection closed.\n");
			break;
		}

		Lsocket.receive_len = ret;
		ret = callback_Labview_Callback(&Lsocket);
		if(ret < 0)
		{
			printf("callback _labview_stock error!\n");
		}
		else
		{

			ret = send(client_socket, Lsocket.reply_buff, Lsocket.reply_len, 0);
			printf("S");
			if(ret == -1)
			{
				error = 1;
				break;
			}
		}
	}

	shutdown(client_socket, SD_BOTH);

	closesocket(client_socket);

	return error ? -1 : 0;
}


